#!/bin/python3
# -*- coding:utf-8 -*-
"""
    [模块名]
    By :陈狍子 e4ting@qq.com 2024-12-07 22:19:05
"""
import sys,os
from pdb import set_trace as strace
from traceback  import format_exc as dumpstack
from e4ting import util,log

from models.mysqls import ModelCash,ModelUtxos,db
from core.cache    import CashCache

class Utxo(object):
    # 转账记录
    def __init__(self, who=None, to=None, room=None, game=None, Round=None):
        self.who   = who
        self.to    = to
        self.room  = room
        self.game  = game
        self.Round = Round

    def __call__(self, amount=0, reason=""):
        return self.do_withdraw(amount, reason)

    def do_withdraw(self, amount=0, reason=""):
        if not self.who.withdraw(amount):
            return False
        self.to.deposit(amount)
        # self.create_record(amount, reason)
        return True

    def create_record(self, amount, reason=""):
        utxo = ModelUtxos(
                who=self.who.uid,
                to=self.to.uid,
                amount=amount,
                room=str(self.room.uid) if self.room else "0",
                game=self.game.uid if self.game else "0",
                roundid=str(self.Round) if self.Round else "0",
                allin=False,
                reason=reason)
        db.session.add(utxo)
        db.session.commit()
        return utxo.id

class Account(object):
    """ 玩家积分账户 """
    bank = None
    def __init__(self, uid=""):
        self.uid = uid

    def init(self):
        self.balance = self.raw_balance
        return self

    def __int__(self):
        return self.balance

    def create_record(self, name, detail=""):
        item = db.session.query(ModelCash).filter(ModelCash.uid==self.uid).first()
        if item:
            return True
        cash = ModelCash(
            uid=self.uid,
            name=name,
            amount=0,
            detail=detail,
            )
        db.session.add(cash)
        db.session.commit()
        return True

    def delete(self):
        return db.session.query(ModelCash).filter(ModelCash.uid==self.uid).update({ModelCash.removed : True})

    def init_cash(self, amount=2000):
        utxo = Utxo(who=Account.get_bank(), to=self)
        utxo.do_withdraw(amount, "账号创建")

    @property
    def raw_balance(self):
        item = db.session.query(ModelCash).filter(ModelCash.uid==self.uid).first()
        if not item:
            return 0
        return item.amount

    def update_record(self, amount):
        return db.session.query(ModelCash).filter(ModelCash.uid==self.uid).update({ModelCash.amount : ModelCash.amount + amount})

    def deposit(self, amount):
        """ 汇入 """
        self.balance += amount
        self.update_record(amount)
        return True

    def withdraw(self, amount=0):
        """ 转出 """
        if amount <= 0:
            log.error("转出额度不能小于0")
            return False

        if self.balance < amount:
            log.error("转出额度不能大于账户余额 {self.balance}".format(self=self))
            return False

        self.balance -= amount
        self.update_record(-amount)
        log.info("{self} 转出成功，余额: {self.balance}".format(self=self))
        return True

    def __repr__(self):
        return "{self.uid} 账户".format(self=self)

    @classmethod
    def get_bank(cls):
        if cls.bank == None:
            cls.bank = Account("bank").init()
        return cls.bank

class VirtualAccount(Account):
    def __init__(self, uid):
        self.uid     = uid

    def init(self):
        return self

    def delete(self):
        pass

    def __int__(self):
        cache = CashCache(self.uid)
        return int(cache.amount or 0)

    def init_cash(self, amount=2000):
        # cache = CashCache(self.uid)
        # cache.set(amount=amount)
        utxo = Utxo(who=self.get_bank(), to=self)
        utxo.do_withdraw(amount, "账号创建")

    def create_record(self, name, detail=""):
        cache = CashCache(self.uid)
        cache.set(name=name, detail=detail)

    def deposit(self, amount):
        cache   = CashCache(self.uid)
        balance = cache.change(amount=amount)
        log.info("{self} 转入 {amount} 成功，余额: {balance}".format(self=self, amount=amount, balance=balance))
        return True

    def withdraw(self, amount=0):
        cache = CashCache(self.uid)
        if amount <= 0:
            log.error("转出额度不能小于0")
            return False

        if int(self) < amount:
            log.error("转出额度不能大于账户余额 {cache.amount}".format(self=self, cache=cache))
            return False

        balance = cache.change(amount=-amount)
        log.info("{self} 转出 {amount} 成功，余额: {balance}".format(self=self, amount=amount, balance=balance))
        return True

    @classmethod
    def get_bank(cls):
        bank = VirtualAccount("bank").init()
        cache = CashCache("bank")
        if not cache.exists():
            bank.create_record(name="银行", detail="银行有一个亿")
            bank.init_cash(amount=10**8)
        return bank

